package com.gsoe.problem.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import com.gsoe.base.enumeration.ProblemType;
import com.gsoe.base.enumeration.TestStatus;
import com.gsoe.base.exception.JudgeException;
import com.gsoe.base.exception.ProblemException;
import com.gsoe.base.model.Result;
import com.gsoe.base.model.User;
import com.gsoe.base.utils.UserUtil;
import com.gsoe.problem.client.JudgeClient;
import com.gsoe.problem.dto.TestDTO;
import com.gsoe.problem.mapper.TestMapper;
import com.gsoe.problem.mapper.TestProblemMapper;
import com.gsoe.problem.po.Problem;
import com.gsoe.problem.po.ProblemChoose;
import com.gsoe.problem.po.Test;
import com.gsoe.problem.po.TestProblem;
import com.gsoe.problem.service.ProblemChooseService;
import com.gsoe.problem.service.TestProblemService;
import com.gsoe.problem.vo.ProblemVO;
import com.gsoe.problem.vo.TestProblemVO;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.time.Duration;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 测验与题目中间表 服务实现类
 * </p>
 *
 * @author xiaoma
 * @since 2024-10-27
 */
@Service
public class TestProblemServiceImpl extends ServiceImpl<TestProblemMapper, TestProblem> implements TestProblemService {
    @Autowired
    private TestProblemMapper testProblemMapper;

    @Autowired
    private TestMapper testMapper;

    @Autowired
    private ProblemChooseService problemChooseService;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private JudgeClient judgeClient;

    @Override
    public TestProblemVO getTestProblemList(Long textId) {
        User loginUser = UserUtil.getLoginUser();
        Test test = testMapper.selectOne(new QueryWrapper<Test>()
                .eq("id", textId)
                .eq("user_id", loginUser.getId())
        );
        if (test == null) {throw new ProblemException("无此测验记录");}
        Long remainingTime= Duration.between(LocalDateTime.now(),test.getCreateTime()).toSeconds()+60L*test.getTime();
        if(!TestStatus.JOIN.equals(test.getStatus())){remainingTime=-1L;}
        List<Problem>textProblemList =testProblemMapper.getTestProblemList(textId,loginUser.getId());
        Map<Integer, List<ProblemVO>> collected = getTypeProblemVOListMapByProblemList(textProblemList);

        Result<Map<Long, String>> testCache = judgeClient.getTestCache(textId);
        if(testCache.getCode()!=200){
            throw new JudgeException(testCache.getMsg());
        }


        TestProblemVO testProblemVO = new TestProblemVO();
        testProblemVO.setBigList(collected.get(ProblemType.BIG));
        testProblemVO.setJudgeList(collected.get(ProblemType.JUDGE));
        testProblemVO.setFillList(collected.get(ProblemType.FILL));
        testProblemVO.setMultipleChooseList(collected.get(ProblemType.MULTIPLE));
        testProblemVO.setSingleChooseList(collected.get(ProblemType.SINGLE));
        testProblemVO.setRemainingTime(remainingTime);
        testProblemVO.setCache(testCache.getData());



        return testProblemVO;
    }

    public Map<Integer, List<ProblemVO>> getTypeProblemVOListMapByProblemList(List<Problem> problemList) {
        List<Long> problemIdList = problemList.stream().map(Problem::getId).toList();
        if(CollectionUtil.isEmpty(problemIdList))return new HashMap<>();
        Map<Long, List<ProblemChoose>> problemIdProblemChooseMap = problemChooseService.list(new QueryWrapper<ProblemChoose>()
                .in("problem_id", problemIdList)
        ).stream().collect(Collectors.groupingBy(ProblemChoose::getProblemId));


        Map<Integer, List<ProblemVO>> collected = problemList.stream().map(problem -> {
            ProblemVO problemVO = new ProblemVO();
            BeanUtils.copyProperties(problem, problemVO);

            if(CollectionUtil.isEmpty(problemIdProblemChooseMap.get(problem.getId())))
                problemVO.setOptionDescribe(new ArrayList<>());
            else{
                problemVO.setOptionDescribe(
                        problemIdProblemChooseMap.get(problem.getId()).stream().map(ProblemChoose::getOptionDescribe).toList()
                );
            }
            return problemVO;
        }).collect(Collectors.groupingBy(ProblemVO::getType));
        return collected;
    }
}
